home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 37 / IOPROG_37.ISO / SOFT / Multilizer.exe / disk1 / data1.cab / data1 / [Group9]VCL Source Standard / ivamulti.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-08-12  |  7.7 KB  |  344 lines

  1. unit IvAMulti;
  2.  
  3. interface
  4.  
  5. uses
  6. {$IFDEF WIN32}
  7.   Windows,
  8. {$ELSE}
  9.   WinTypes, WinProcs,
  10. {$ENDIF}
  11.   SysUtils, Classes,
  12.   IvDictio;
  13.  
  14. type
  15.   { These are not used any more by ML 4.0 }
  16.  
  17.   EIvSorting = class(EIvMulti);
  18.   EIvTranslationRowIncomplete = class(EIvMulti);
  19.   EIvNullNativeString = class(EIvMulti);
  20.  
  21.   TIvStorage = (ivsFile, ivsEmbedded{$IFDEF WIN32}, ivsResource{$ENDIF});
  22.  
  23.   TIvCustomFileDictionary = class(TIvDictionary)
  24.   protected
  25.     FFileName: String;
  26.     FTranslations: TList;
  27.     FStorage: TIvStorage;
  28.  
  29.     function GetFileName: String;
  30.  
  31.     function GetTranslation(i: Integer): TIvTranslation;
  32.  
  33.     procedure ClearTranslations;
  34.  
  35.     function Find(str: String): Integer;
  36.     function FindContext(const str, form, component: String): Integer;
  37.  
  38.     procedure QuickSort(left, right: Integer);
  39.     procedure ContextQuickSort(left, right: Integer);
  40.     procedure Sort;
  41.  
  42.     procedure LanguageChanged(languageChanged, localeChanged: Boolean); override;
  43.  
  44.     procedure LoadTranslation; virtual; abstract;
  45.  
  46.     function ExpandFileName(const fileName: String): String;
  47.  
  48.     function GetTranslationCount: Integer; override;
  49.  
  50.   public
  51.     constructor Create(owner: TComponent); override;
  52.     destructor Destroy; override;
  53.  
  54.     function TranslateString(
  55.       const str: String;
  56.       var translation: String): Boolean; override;
  57.  
  58.     function TranslateContextString(
  59.       const str, form, component: String;
  60.       var translation: String): Boolean; override;
  61.  
  62.     function CanBeOpened: Boolean; override;
  63.  
  64.     property Translations[i: Integer]: TIvTranslation read GetTranslation;
  65.  
  66.   published
  67.     property FileName: String read GetFileName write FFileName;
  68.     property Storage: TIvStorage read FStorage write FStorage default ivsFile;
  69.   end;
  70.  
  71. implementation
  72.  
  73. uses
  74.   Forms;
  75.  
  76. { TIvCustomFileDictionary }
  77.  
  78. constructor TIvCustomFileDictionary.Create(owner: TComponent);
  79. begin
  80.   inherited Create(owner);
  81.   FTranslations := TList.Create;
  82.   FStorage := ivsFile;
  83. end;
  84.  
  85. destructor TIvCustomFileDictionary.Destroy;
  86. begin
  87.   ClearTranslations;
  88.   FTranslations.Free;
  89.   inherited Destroy;
  90. end;
  91.  
  92. function TIvCustomFileDictionary.GetTranslationCount: Integer;
  93. begin
  94.   Result := FTranslations.Count;
  95. end;
  96.  
  97. function TIvCustomFileDictionary.ExpandFileName(const fileName: String): String;
  98. var
  99.   str: String;
  100. begin
  101.   Result := fileName;
  102.   if FStorage = ivsFile then
  103.   begin
  104.     str := SysUtils.ExpandFileName(Result);
  105.     if FileExists(str) then
  106.       Result := str
  107.     else if ExtractFilePath(fileName) = '' then
  108.     begin
  109.       str := ExtractFilePath(Application.ExeName) + fileName;
  110.       if FileExists(str) then
  111.         Result := str;
  112.     end;
  113.   end;
  114. end;
  115.  
  116. function TIvCustomFileDictionary.GetFileName: String;
  117. begin
  118. {$IFNDEF IVVB}
  119.   if not IsDesignTime then
  120.     FFilename := ExpandFileName(FFilename);
  121. {$ENDIF}
  122.   Result := FFilename;
  123. end;
  124.  
  125. function TIvCustomFileDictionary.CanBeOpened: Boolean;
  126. begin
  127.   Result := (FStorage <> ivsFile) or ((FileName <> '') and FileExists(FileName));
  128. end;
  129.  
  130. function TIvCustomFileDictionary.GetTranslation(i: Integer): TIvTranslation;
  131. begin
  132.   Result := FTranslations[i];
  133. end;
  134.  
  135. procedure TIvCustomFileDictionary.ClearTranslations;
  136. begin
  137.   while FTranslations.Count > 0 do
  138.   begin
  139.     TIvTranslation(FTranslations[0]).Free;
  140.     FTranslations.Delete(0);
  141.   end;
  142. end;
  143.  
  144. procedure TIvCustomFileDictionary.LanguageChanged(
  145.   languageChanged, localeChanged: Boolean);
  146. begin
  147.   if languageChanged then
  148.     LoadTranslation;
  149.   inherited LanguageChanged(languageChanged, localeChanged);
  150. end;
  151.  
  152. function TIvCustomFileDictionary.Find(str: String): Integer;
  153. var
  154.   l, h, i, c, len: Integer;
  155.   thisStr: String;
  156. begin
  157.   l := 0;
  158.   h := FTranslations.Count - 1;
  159.  
  160.   if ContextType = [] then
  161.   begin
  162.     { Flat dictionary }
  163.  
  164.     while l <= h do
  165.     begin
  166.       i := (l + h) div 2;
  167.       c := SysUtils.CompareStr(Translations[i].Str, str);
  168.       if c = 0 then
  169.       begin
  170.         Result := i;
  171.         Exit;
  172.       end
  173.       else if c < 0 then
  174.         l := i + 1
  175.       else
  176.         h := i - 1;
  177.     end;
  178.   end
  179.   else
  180.   begin
  181.     { Context sensitive dictionary.
  182.       Search the first row having the same native part as the give string. }
  183.  
  184.     str := str + CONTEXT_SEPARATOR_C;
  185.     len := Length(str);
  186.     while l <= h do
  187.     begin
  188.       i := (l + h) div 2;
  189.       thisStr := Translations[i].Str + CONTEXT_SEPARATOR_C;
  190.       c := SysUtils.CompareStr(thisStr, str);
  191.       if (c = 0) and (Length(thisStr) = len) then
  192.       begin
  193.         Result := i;
  194.         Exit;
  195.       end
  196.       else if c < 0 then
  197.         l := i + 1
  198.       else
  199.         h := i - 1;
  200.     end;
  201.   end;
  202.  
  203.   Result := -1;
  204. end;
  205.  
  206. function TIvCustomFileDictionary.FindContext(const str, form, component: String): Integer;
  207. var
  208.   l, h, i, c: Integer;
  209.   key: String;
  210. begin
  211.   if ContextType = [] then
  212.   begin
  213.     { Flat dictionary. Ignores the context. }
  214.  
  215.     Result := Find(str);
  216.   end
  217.   else
  218.   begin
  219.     { Context sensitive dictionary.
  220.       Search the first row having the same key as the give string. }
  221.  
  222.     l := 0;
  223.     h := FTranslations.Count - 1;
  224.     key := TIvTranslation.ComposeKey(str, form, component);
  225.     while l <= h do
  226.     begin
  227.       i := (l + h) div 2;
  228.       c := SysUtils.CompareStr(Translations[i].Key, key);
  229.       if c = 0 then
  230.       begin
  231.         Result := i;
  232.         Exit;
  233.       end
  234.       else if c < 0 then
  235.         l := i + 1
  236.       else
  237.         h := i - 1;
  238.     end;
  239.  
  240.     Result := -1;
  241.   end;
  242. end;
  243.  
  244. function TIvCustomFileDictionary.TranslateString(
  245.   const str: String;
  246.   var translation: String): Boolean;
  247. var
  248.   index: Integer;
  249. begin
  250.   index := Find(str);
  251.   Result := index >= 0;
  252.   if Result then
  253.     translation := Translations[index].Current;
  254. end;
  255.  
  256. function TIvCustomFileDictionary.TranslateContextString(
  257.   const str, form, component: String;
  258.   var translation: String): Boolean;
  259. var
  260.   index: Integer;
  261. begin
  262.   index := FindContext(str, form, component);
  263.   Result := index >= 0;
  264.   if Result then
  265.     translation := Translations[index].Current;
  266. end;
  267.  
  268. procedure TIvCustomFileDictionary.QuickSort(left, right: Integer);
  269. var
  270.   i, j: Integer;
  271.   p: String;
  272.   translation: TIvTranslation;
  273. begin
  274.   i := left;
  275.   j := right;
  276.   p := Translations[(left + right) shr 1].Str;
  277.  
  278.   repeat
  279.     while SysUtils.CompareStr(Translations[i].Str, p) < 0 do
  280.       Inc(i);
  281.     while SysUtils.CompareStr(Translations[j].Str, p) > 0 do
  282.       Dec(j);
  283.     if i <= j then
  284.     begin
  285.       translation := FTranslations[i];
  286.       FTranslations[i] := FTranslations[j];
  287.       FTranslations[j] := translation;
  288.       Inc(i);
  289.       Dec(j);
  290.     end;
  291.   until i > j;
  292.  
  293.   if left < j then
  294.     QuickSort(left, j);
  295.  
  296.   if i < right then
  297.     QuickSort(i, right);
  298. end;
  299.  
  300. procedure TIvCustomFileDictionary.ContextQuickSort(left, right: Integer);
  301. var
  302.   i, j: Integer;
  303.   p: String;
  304.   translation: TIvTranslation;
  305. begin
  306.   i := left;
  307.   j := right;
  308.   p := Translations[(left + right) shr 1].Key;
  309.  
  310.   repeat
  311.     while SysUtils.CompareStr(Translations[i].Key, p) < 0 do
  312.       Inc(i);
  313.     while SysUtils.CompareStr(Translations[j].Key, p) > 0 do
  314.       Dec(j);
  315.     if i <= j then
  316.     begin
  317.       translation := FTranslations[i];
  318.       FTranslations[i] := FTranslations[j];
  319.       FTranslations[j] := translation;
  320.       Inc(i);
  321.       Dec(j);
  322.     end;
  323.   until i > j;
  324.  
  325.   if left < j then
  326.     ContextQuickSort(left, j);
  327.  
  328.   if i < right then
  329.     ContextQuickSort(i, right);
  330. end;
  331.  
  332. procedure TIvCustomFileDictionary.Sort;
  333. begin
  334.   if FTranslations.Count = 0 then
  335.     Exit;
  336.  
  337.   if ContextType = [] then
  338.     QuickSort(0, FTranslations.Count - 1)
  339.   else
  340.     ContextQuickSort(0, FTranslations.Count - 1);
  341. end;
  342.  
  343. end.
  344.